package com.mini.mybatis.mybatisministep07.sqlsession.defaults;

import com.mini.mybatis.mybatisministep07.executor.Executor;
import com.mini.mybatis.mybatisministep07.mapping.MappedStatement;
import com.mini.mybatis.mybatisministep07.sqlsession.SqlSession;
import com.mini.mybatis.mybatisministep07.sqlsession.configuration.Configuration;

import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DefaultSqlSession implements SqlSession {

    private Configuration configuration;

    private Executor executor;

    public DefaultSqlSession(Configuration configuration, Executor executor){
        this.configuration = configuration;
        this.executor = executor;
    }

    @Override
    public <T> T selectOne(String statement) {
        MappedStatement mappedStatement = configuration.getMapStatement(statement);
//        return (T) ("被代理了 " + "statement" + mappedStatement.getId() + " sql语句 "+mappedStatement.getSql());
        return null;
    }

    @Override
    public <T> T selectOne(String statement, Object parameter) {

        try {
            MappedStatement ms = configuration.getMapStatement(statement);
            List<T> list = executor.query(ms, parameter, Executor.NO_RESULT_HANDLER, ms.getBoundSql());
            return list.get(0);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private <T> List<T> resultSet2Obj(ResultSet resultSet, Class<?> clazz) {
        List<T> list = new ArrayList<>();
        try{
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            while (resultSet.next()){
                T obj = (T) clazz.newInstance();
                for (int i = 1; i <= columnCount; i++) {
                    Object value = resultSet.getObject(i);
                    String columnName = metaData.getColumnName(i);
                    String setMethod = "set" + columnName.substring(0,1).toUpperCase() + columnName.substring(1);
                    Method method;
                    if (value instanceof  Timestamp){
                        method = clazz.getMethod(setMethod,Date.class);
                    }else {
                        method = clazz.getMethod(setMethod,value.getClass());
                    }
                    method.invoke(obj,value);
                }
                list.add(obj);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public <T> T getMapper(Class<T> type) {
        return configuration.getMapper(type,this);
    }

    @Override
    public Configuration getConfiguration() {
        return configuration;
    }
}
